#ifndef CGLOBAL_H
#define CGLOBAL_H




#include <QString>
#include <QTime>
#include <QFont>
#include <QLabel>
#include <QDateTime>
#include <QMap>



//#pragma execution_character_set("utf-8")


#if 1

#define PC

#endif


// BASE64转换格式控制
#if 1

#define BASE64

#endif

#ifndef BASE64

    #if 0

    #define RAWDATA

    #endif

    #ifndef RAWDATA

    #define HEXDATA

    #endif

#endif


#ifndef PC
// 平台接口
#define PLT_INTERFACE

#define TWO_NUMBERS                                                               // 数据包中2位年份表示


// 双字节解析
#define DWORD

#endif





#ifdef DWORD

// 最小解析单位（2进制长度）
#define WORD_LEN 16

#else

#define WORD_LEN 8

#endif

// 最小解析单位（2进制长度）用16进制表示时的字符串长度,例如最小解析单位为1个字节，那么1个字节的16进制表示为FF，占2个字符长度
#define WORD_STR_LEN ((WORD_LEN / 8) * 2)


#define DEVICES_CAPACITY 10                                                         // 设备
#define CYCLES_CAPACITY 1000                                                        // 画曲线时所用到的保存数据的数组长度
#define RECEIVE_CYCLES_CAPACITY 1000                                                // 网络获取的数据包数组初始长度




//#define WITHOUT_TITLE                                                               // 模拟显示界面的变量选择下拉框不显示TITLE类型


// 关于菜单显示内容

#ifdef BIT_64
#define ABOUT_BIT_VERSION QString("x86_64")
#else
#define ABOUT_BIT_VERSION QString("x86")
#endif

#if _MSC_VER > 1916 && _MSC_VER <= 1929
#define MSVC_VER QString("2019")
#elif _MSC_VER > 1929
#define MSVC_VER QString("2022")
#endif


#ifdef __GNUC__
#define COMPILER_NAME (QString("GCC ") + QString::number(__GNUC__))
#endif

#ifdef _MSC_VER
#define COMPILER_NAME (QString("MSVC ") + MSVC_VER)
#endif

#define ABOUT_TEXT_VERSION QString("Ver_1.0.9")
#define ABOUT_TEXT_COPYRIGHT QString("Copyright ©2022-2052 上海富欣智能交通控制有限公司.      ")
#define ABOUT_TEXT (QString("基于Qt ") + QT_VERSION_STR + "(" + COMPILER_NAME + ", " + ABOUT_BIT_VERSION + ")开发\n\n" \
    + "编译于" + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + "\n\n" \
    + ABOUT_TEXT_COPYRIGHT)



#define CONFIG_PATH QString("Config/Config.xml")



// 控制区域
#define VERTICAL_MINORS 15                                                              // 需要减去的纵向高度
#define CONTROL_AREA_EQUAL_PARTS 5                                                      // 控制区域等分数量
#define HOME_PAGE QString("首页")
#define PAGE_UP QString("上翻")
#define PAGE_DOWN QString("下翻")
#define END_PAGE QString("尾页")
#define BUTTON_MAX_WIDTH 32                                                             // 按钮最大宽度
#define LABEL_MAX_WIDTH 50                                                              // 标签最大宽度
#define LINEEDIT_MAX_WIDTH 32                                                           // 编辑行最大宽度
#define COMBOBOX_WIDTH_MULTIPLE 1.5                                                     // 下拉框宽度与字符串宽度的倍数


//模拟显示区域设定
//#define DRAW_AREA_WIDTH 1000                                                        // 绘图区域宽度
//#define DRAW_AREA_HEIGHT 500                                                        // 绘图区域高度
#define AUXILIARY_AREA_WIDTH 800                                                    // 辅助区域宽度
//#define RULER_AREA_HEIGHT 30                                                        // 刻度尺区域高度
#define DRAW_AREA_BACKGROUND "#394E5F"                                              // 绘图区域背景色
#define MAJOR_SCALE_NUMBERS 10                                                      // 主刻度尺数量
#define MINOR_SCALE_NUMBERS 50                                                      // 小刻度数量
#define GRID_PER_MAJOR_SCALE MINOR_SCALE_NUMBERS / MAJOR_SCALE_NUMBERS
#define TEXTBROWSER_TEXT_WIDTH 140                                                  // 文本框中一行固定像素宽度
#define SPACE_LINE_TO_EDGE 5                                                        // 纵向线条距离绘图区域边界的距离
#define LINE_WIDTH 2                                                                // 线条宽度
#define MILLSECONDS_PER_CYCLE 100                                                   // 每周期毫秒数
#define LINE_LABEL_START_X 5                                                        // 标签起始横坐标
#define LINE_LABEL_START_Y 5                                                        // 标签起始纵坐标
#define LINE_LABEL_WEIGHT 200                                                       // 标签固定宽度
#define LINE_LABEL_HEIGHT 25                                                        // 标签固定高度
#define SPACE_BETWEEN_TWO_LABELS 5                                                  // 图例中2个标签的距离
#define CURRENT_CYCLE_COLOR QColor(255,0,0)                                         // 当前周期颜色
#define NORMAL_CYCLE_COLOR QColor(80,80,80)                                      // 一般周期颜色
#define LEGEND_PREFIX " —— "                                                        // 图例前缀
#define COMBOBOX_ZOOM_DEFAULT_INDEX 4                                               // 缩放下拉框默认选项
#define LABEL_VECTOR_DEFAULT_SIZE 20                                                // 图例标签数组默认大小
#define TEXTBROWSER_LABEL_HEIGHT 20                                                 // 文本显示区域标签高度




// 工具栏区域显示设定
#define CYCLE_TITLE_WIDTH 70                                                       // 周期标题标签宽度
#define CYCLE_WIDTH 60                                                              // 周期标签宽度
#define TIME_STAMP_WIDTH 200                                                        // 时间戳标签宽度
#define SPACE_WIDTH_PERCENT 20                                                      // 空格宽度
#define REGULAR_SAVE_SPACE_WIDTH 200                                                // 定期保存日志勾选框之前的空格宽度
#define DISPLAY_CYCLE_TITLE "周期号:"                                               // 周期标题显示内容
#define YEAR_SEPARATOR "/"                                                          // 年份分隔符
#define TIME_SEPARATOR ":"                                                          // 时间分隔符
#define MILLISECOND_SEPARATOR "."                                                    // 毫秒分隔符
#define YEAR_TIME_SEPARATOR "  "                                                    // 日期和时间分隔符






#ifdef TWO_NUMBERS
    #define YEAR_PREFIX "20";                                                       // 数据包中为2位年份时使用
#endif






// 工具栏相关字符串
#define STRING_LABEL_CYCLE_NUMBER QString("CycleNumber")
#define STRING_LABEL_YEAR QString("Year")
#define STRING_LABEL_MONTH QString("Month")
#define STRING_LABEL_DAY QString("Day")
#define STRING_LABEL_HOUR QString("Hour")
#define STRING_LABEL_MINUTE QString("Minute")
#define STRING_LABEL_SECOND QString("Second")
#define STRING_LABEL_MILLISECOND QString("Millisecond")

static const QMap<QString, int> MAP_TOOLBAR_STRING {
    {"CYCLENUMBER", 0},
    {"YEAR", 1},
    {"MONTH", 2},
    {"DAY", 3},
    {"HOUR", 4},
    {"MINUTE", 5},
    {"SECOND", 6},
    {"MILLISECOND", 7}
};


// 大小端相关字符串
#define STRING_LABEL_BIG_ENDIAN QString("Big")
#define STRING_LABEL_LITTLE_ENDIAN QString("Little")


// XML节点相关字符串
#define STRING_NODE_FORMAT_SETTINGS QString("Format_Settings")                          // 根节点
#define STRING_NODE_CHECK_INFOS QString("Check_Infos")
#define STRING_NODE_BODY QString("Body")

// Check_Infos节点相关字符串
#define STRING_LABEL_CHECK_INFOS_PROJECT QString("Project")
#define STRING_LABEL_CHECK_INFOS_PRODUCT QString("Product")
#define STRING_LABEL_CHECK_INFOS_BASELINE QString("BaseLine")
#define STRING_LABEL_CHECK_INFOS_DATE QString("Date")

// Body节点相关字符串
#define STRING_NODE_ENUMERATED QString("Enumerated")
#define STRING_NODE_FRAME QString("Frame")


// Enumerated节点相关字符串
#define STRING_LABEL_ENUMERATED_LABEL QString("Label")
#define STRING_NODE_VALUE QString("Value")
#define STRING_LABEL_VALUE_CODE QString("Code")
#define STRING_LABEL_VALUE_LABEL QString("Label")

// Frame节点相关字符串
#define STRING_LABEL_FRAME_ENDIAN QString("Endian")
#define STRING_NODE_FIELD QString("Field")
#define STRING_LABEL_FIELD_LABEL QString("Label")
#define STRING_NODE_COMPUTATION QString("Computation")
#define STRING_NODE_DISPLAY QString("Display")
#define STRING_LABEL_COMPUTATION_TYPE QString("Type")
#define STRING_LABEL_COMPUTATION_FIRST_BIT_POSITION QString("First_Bit_Position")
#define STRING_LABEL_COMPUTATION_BIT_COUNT QString("Bit_Count")
#define STRING_LABEL_DISPLAY_TYPE QString("Type")
#define STRING_LABEL_DISPLAY_ENUMERATED_LABEL QString("Enumerated_Label")
#define STRING_LABEL_DISPLAY_DECIMAL_DIGITS QString("Decimal_Digits")
#define STRING_LABEL_DISPLAY_UNIT QString("Unit")
#define STRING_NODE_POSITION QString("Position")
#define STRING_NODE_RANGE QString("Range")
#define STRING_LABEL_POSITION_PAGE QString("Page")
#define STRING_LABEL_POSITION_ROW QString("Row")
#define STRING_LABEL_POSITION_COLUMN QString("Column")
#define STRING_LABEL_RANGE_MIN QString("Min")
#define STRING_LABEL_RANGE_MAX QString("Max")

// 数据类型字符串
#define STRING_DATATYPE_UNSIGNED_INTEGER "UINT"
#define STRING_DATATYPE_SIGNED_INTEGER "INT"


// 显示相关字符串
#define STRING_DISPLAY_TYPE_HEXADECIMAL "Hex"
#define STRING_DISPLAY_TYPE_DECIMAL "Dec"
#define STRING_DISPLAY_TYPE_BINARY "Bin"
#define STRING_DISPLAY_TYPE_ENUMERATED "Enum"
#define STRING_DISPLAY_TYPE_TITLE "Title"

static const QMap<QString, int> MAP_DISPLAY_TYPE {
    {"HEX", 16},
    {"DEC", 10},
    {"BIN", 2},
    {"ENUM", 1},
    {"TITLE", 0}
};


// Check_Infos节点
struct _check_infos
{
    QString* Project = NULL;                                                               // 项目名称
    QString* Product = NULL;                                                               // 产品名称
    QString* BaseLine = NULL;                                                              // 产品基线号
    QString* Date = NULL;                                                                  // 日期
};


// Value节点
struct _value
{
    int* Code = NULL;                                                                      // 枚举类型值
    QString* Label = NULL;                                                                 // 枚举类型值对应的标签
};



// Enumerated节点
struct _enumerated
{
    QString* Label = NULL;                                                                 // 枚举类型名称
    QVector<struct _value*>* Value = NULL;                                                   // 枚举类型值和标签对应关系
};




// Computation节点，用于数据提取
struct _computation
{
    QString* Type = NULL;                                                                  // 字段类型
    unsigned int* First_Bit_Position = NULL;                                               // 字段起始比特位位置
    unsigned int* Bit_Count = NULL;                                                        // 字段的比特位长度
    //unsigned int* Quantum;                                                        // 字段量级
    //unsigned int* Offset;                                                         // 字段的偏移量
};




// Position节点，数据显示位置，标签的显示位置为(Row, Column-1)，数据的显示为(ROW, Column)
struct _position
{
    unsigned int* Page = NULL;                                                             // 显示的页面数
    unsigned int* Row = NULL;                                                              // 在该页显示的行数
    unsigned int* Column = NULL;                                                           // 在该页显示的列数
};




// Range节点，用于画图
struct _range
{
    int* Min = NULL;                                                                       // 该字段的最小值
    int* Max = NULL;                                                                       // 该字段的最大值
};



// Display节点，显示相关信息
struct _display
{
    QString* Type = NULL;                                                                  // 该字段显示时的类型
    QString* Enumerated_Label = NULL;                                                      // 枚举类型标签
    unsigned int* Decimal_Digits = NULL;                                                   // 小数位数
    QString* Unit = NULL;                                                                  // 显示的单位
    struct _position* Position = NULL;                                                     // 显示位置
    struct _range* Range = NULL;                                                           // 取值范围
};



// Field节点
struct _field
{
    QString* Label = NULL;                                                                 // 显示的标签
    struct _computation* Computation = NULL;                                               // 解析字段所需的相关信息
    struct _display* Display = NULL;                                                       // 显示字段所需的相关信息
    QString* value = NULL;                                                                 // 字段解析后的值, 用于在模拟显示界面显示当前周期的值
};




// Frame帧节点
struct _frame
{
//    QString* Label;                                                               // 帧的标签
//    QString* Type;                                                                // 帧类型
//    QString* Id;                                                                  // 帧ID
//    unsigned int* Byte_Count;                                                     // 总长度
//    unsigned int* Total_Pages;                                                    // 显示总页数
//    struct _header* Header;                                                       // 数据包头
    QString* Endian = NULL;                                                                // 大小端
    QVector<struct _field*>* Field = NULL;                                                   // 数据域
};




// Body节点
struct _body
{
    QVector<struct _enumerated*>* Enumerated = NULL;                                         // 枚举类型列表
    struct _frame* Frame = NULL;                                                           // 帧
};


// 根节点
struct _format_settings
{
    struct _check_infos* Check_Infos = NULL;                                               // 校验信息
    struct _body* Body = NULL;                                                             // 内容
};




// 工具栏结构体
typedef struct _tool_bar_data
{
   unsigned int* start = NULL;
   unsigned int* len = NULL;
   QString* title = NULL;
   QString* showValue = NULL;
}*pTOOLBAR_DATA;



// 单个数据显示内容，通过判断指定是否为空来决定显示标题还是数据
typedef struct _data_context
{
    QString* title = NULL;                                                                 // 对应_field结构体的Label属性
    QString* computationType = NULL;                                                       // 对应_field结构体中Computation下的Type(原data_type)
    int* start = NULL;                                                                     // 对应_field结构体中Computation下的First_Bit_Position(原来在栈空间)
    int* len = NULL;                                                                       // 对应_field结构体中Computation下的Bit_Count(原来在栈空间)
    QString* displayType = NULL;                                                           // 对应_field结构体中Display下的Type(原来是type)
    QString* enumeratedLabel = NULL;                                                       // 对应_field结构体中Display下Enumerated_Label(原来是enumerated_label)
    QString* unit = NULL;                                                                  // 对应_field结构体中Display下的Unit
    int* row = NULL;                                                                       // 对应_field结构体中Display下Position的Row(原来在栈空间)
    int* column = NULL;                                                                    // 对应_field结构体中Display下Position的Column(原来在栈空间)
    int* max = NULL;                                                                       // 对应_field结构体中Display下Range的Max
    int* min = NULL;                                                                       // 对应_field结构体中Display下Range的Max
    int* red = NULL;                                                                       // 画曲线时RGB对应的Red值，数显界面不需要该值
    int* green = NULL;                                                                     // 画曲线时RGB对应的Green值，数显界面不需要该值
    int* blue = NULL;                                                                      // 画曲线时RGB对应的Blue值，数显界面不需要该值
    bool* show_flag = NULL;                                                                // 在模拟显示界面画图时是否画出该曲线，数显界面不需要该值(原来在栈空间)
    QVector<int*>* allCyclesIntValues = NULL;                                              // 每周期的数值，数显界面不需要该值(原来是values)
    QVector<QString*>* allCyclesStrValues = NULL;                                          // 每周期对应的字符串值，数显界面不需要该值(原来是show_values)
    QString* currentCycleValue = NULL;                                                     // 当前周期的显示值(原来是data)
    int* bit_pos = NULL;                                                                  // 双字节是的位序号
}*PDATA_CONTEXT;





// 单页显示的数组
typedef struct _page_context
{
    QVector<PDATA_CONTEXT>* context = NULL;
}*pPAGE_CONTEXT;




typedef struct _options
{
    //全局
    QString* pWindowBackgroundColor = NULL;                                                         // 主窗口背景色
    QString* pToolbarBackgroundColor = NULL;                                                        // 工具栏背景色
    QString* pDefaultPath = NULL;                                                                   // 日志默认路径
    int* pMultipleCyles = NULL;                                                                     // 快进周期数
    QFont* pFont = NULL;                                                                            // 标签显示字体类型
    int* pFontSize = NULL;                                                                          // 标签显示字体大小
    int* pRegularSaveTime = NULL;                                                                   // 定期保存时长

    //数字界面
    QString* pTitleLabelBackgroundColor = NULL;                                                     // 标题标签背景色
    QString* pValueLabelBackgroundColor = NULL;                                                     // 值标签背景色
    QString* pLabelTextColor = NULL;                                                                // 标签文字颜色

    //图形界面
    QString* pImageAreaBackgroundColor = NULL;                                                      // 图形区域背景色
    QString* pLegendAreaBackgroundColor = NULL;                                                     // 图例区域背景色
    int* pLegendLabelHeight = NULL;                                                                 // 图例标签高度
}*pOPTIONS;




typedef struct _commons
{
    int PLT_REQUEST_MSG;                                                        // 平台版本连接时发送的连接请求
    int PLT_MSG_TYPE;                                                         // 调试信息过滤字段
    bool WITHOUT_TITLE;                                                              // 模拟显示界面的变量选择下拉框不显示TITLE类型
    float SYSTEM_CYCLE;                                                             // 系统周期（单位：秒）
    int DEFAULT_WIDTH;
    int DEFAULT_HEIGHT;
    int COLUMNS_PER_ROW;                                                           // 每行显示4列内容
    int ROWS_PER_COLUMN;                                                          // 每列显示20行内容
    int HEIGHT_PERCENT;                                                           // 数字显示区域高度所占主窗口高度百分比
    int HORIZONTAL_SIDE_SPACING;                                                   // 横向边距5
    int VERTICAL_SIDE_SPACING;                                                    // 纵向边距5

//    //模拟显示区域设定
    int DRAW_AREA_WIDTH;                                                       // 绘图区域宽度
    int DRAW_AREA_HEIGHT;                                                       // 绘图区域高度
    int DRAW_AREA_WIDTH_PERCENT;                                                          // 图形区域宽度占比
    int RULER_AREA_HEIGHT;                                                        // 刻度尺区域高度

}*pCOMMONS;

typedef struct _page_area_attr
{
   uint maxPage;
   uint currentPage;
}PAGE_AREA_ATTR,*pPAGE_AREA_ATTR;

typedef struct _cycle_attr
{
    int maxCycle;
    int currentCycle;                                                   // 起始为1
}CYCLE_ATTR,*pCYCLE_ATTR;


enum SHOW_MODE
{
    DIGITAL,
    IMAGE
};


enum DATA_SOURCE
{
    LOGFILE,
    UDP
};

static const QMap<QString, int> MAP_LABEL_TYPE {
    {"TITLE" , 0},
    {"VALUE" , 1}
};


typedef struct _system
{
    QString ip;
    QString port;
}SYSTEM;

// 字符串值
typedef struct _str_value{
    QString value;   // 该字符串的值
    QString type;    // 该字符串的类型
}STRVALUE;




#endif // CGLOBAL_H
